package yf.platform.biz;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.yfsoft.comm.util.StringUtil;
import org.yfsoft.comm.util.TimeUtil;

import yf.platform.bo.BizResult;
import yf.platform.ctl.GlobalKey;
import yf.platform.dao.DaoExecuteException;


public class TplService extends Service {

	@SuppressWarnings("unchecked")
	public BizResult list(Map<String,String> input) throws Throwable{
		Map<String,Object> user = rst.getSissAttribute(GlobalKey.USER);
		String m_id = input.get("m_id");
		Map<String,Object> m = null;
		if("admin".equals(user.get("ui_username"))){
			m = this.daoSupport.findOne("sys_model",null,"m_id = "+m_id);
		}else{
			m = this.daoSupport.findOne("sys_model m,mdl_security ms,sys_r_sg_sr gr","m.*,gr.*",
					StringUtil.format(" m.m_id = ms.ts_model and ms.ts_sg = gr.r_g and gr.r_r = (select o_role from usr_obs where o_id = {0}) and m.m_id = {1}", user.get("ui_dept"),m_id));
		}
		rst.setReqAttribute("model", m);
		List<Map<String,Object>> controls = this.daoSupport.find("sys_model_control mc,sys_control c", 
				"mc.*,c.*",
				"mc.mc_control_id = c.c_id and mc.mc_model_id = "+m_id,
				"mc_index");
		if(controls.size()<1){
			return rst.setCode(-10)
				.setMsg("未设置栏位信息");
		}
		rst.setReqAttribute("controls", controls);
		
		String where = null;
		if("1".equals(m.get("m_private").toString())){
			where = m.get("m_user").toString() + " = " +user.get("ui_id"); 
		}
		//获取到用户的配置信息
		Map<String,String> profile = (Map<String,String>)user.get("ui_profile");
		
		String view = m.get("m_view").toString();
		
		//根据用户的配置信息来决定视图的排序方式
		List<Map<String,Object>> entrys = this.daoSupport.find(view,null,where,profile.containsKey(view)?profile.get(view):"");
		for(Map<String,Object> c : controls){
			Object ds_id = c.get("mc_ds");
			if(null == ds_id) continue;
			if("0".equals(ds_id)) continue;
			for(int i = 0 ;i < entrys.size();i++){
				Map<String,Object> e = entrys.get(i);
				e.put(c.get("mc_attr_name").toString(),
						this.getDataValue(Integer.parseInt(ds_id.toString()),e.get(c.get("mc_attr_name")))
						);
				entrys.set(i, e);
			}
		}
		return rst.setCode(0)
			.setReqAttribute("es", entrys)
			.setType(BizResult.REDIRECT)
			.setPage("WIDGETS/TPL/list.jsp");
	}
	
	protected Map<String,String> getControls(String m_id) throws Throwable{
		
		Map<String,String> tmp = new HashMap<String,String>();
		Map<String,Object> m = this.daoSupport.findOne("sys_model",null,"m_id = "+m_id);
		tmp.put("v",m.get("m_view").toString());
		rst.setReqAttribute("model", m);
		List<Map<String,Object>> controls = this.daoSupport.find("sys_model_control mc,sys_control c", 
				"mc.*,c.*",
				"mc.mc_control_id = c.c_id and mc.mc_model_id = "+m_id,
				"mc_index");
		for(int i = 0;i<controls.size();i++){
			Map<String,Object> c = controls.get(i);
			if("1".equals(c.get("mc_pri").toString()))
				tmp.put("pri",c.get("mc_attr_name").toString());
			Object ds_id = c.get("mc_ds");
			if(null == ds_id) continue;
			if("0".equals(ds_id.toString().trim())) continue;
			StringBuffer sb = new StringBuffer();
			List<Map<String,Object>> ds = this.getDataSource("mc_ds",ds_id);
			for(Map<String,Object> d : ds){
				sb.append("<option value='").append(d.get("k")).append("' >").append(d.get("v")).append("</option>");
			}
			c.put("mc_ds", sb.toString());
			controls.set(i, c);
		}
		rst.setCode(0).setReqAttribute("controls", controls);
		return tmp;
	}
	
	public List<Map<String,Object>> getDataSource(String fieldName,Object fieldValue) 
			throws DaoExecuteException{
			Map<String,Object> mc = new HashMap<String,Object>();
			mc.put(fieldName, fieldValue);
			return getDataSource(mc,null);
		
	}
	
	public List<Map<String,Object>> getDataSource(Map<String,Object> mc) 
			throws DaoExecuteException{
		
		return getDataSource(mc,null);
	}
	
	
	/**
	 * 获取控件对应的数据源
	 * @param entry 数据实例
	 * @param mc 模型控件详情
	 * @return 数据源列表信息
	 * @throws DaoExecuteException
	 */
	public List<Map<String,Object>> getDataSource(Map<String,Object> mc,Map<String,Object> entry) {
		Map<String,Object> ds = null;
		if(mc.containsKey("mc_ds")){
			Object ds_id = mc.get("mc_ds");
			ds = this.daoSupport.findOne("sys_ds",null,"ds_id = "+ds_id);
		}else{
			String w = null;
			for(String k : mc.keySet()){
				w = k+" = ";
				Object v = mc.get(k);
				if(v instanceof String){
					w += "'" + v +"'";
				}else{
					w += v;
				}
			}
			
			ds = this.daoSupport.findOne("sys_ds",null,w);
		}
		if(null!=ds && ds.size()>0){
			String ds_type_val = ds.get("ds_type").toString();
			List<Map<String,Object>> mc_ds = null;
			if("map".equals(ds_type_val)){
				mc_ds = new ArrayList<Map<String,Object>>();
				Map<String,Object> data ;
				//1:是,0:否
				String ds_map = ds.get("ds_collection").toString();
				String[] ds_map_split = ds_map.split(",");
				for(String s : ds_map_split){
					data = new HashMap<String,Object>();
					data.put("k", s.substring(0,s.indexOf(":")));
					data.put("v", s.substring(s.indexOf(":")+1));
					mc_ds.add(data);
				}
			}else if("sql".equals(ds_type_val)){
				String sql = ds.get("ds_sql").toString();
				if(null != entry)
					sql = StringUtil.formatSql(sql, entry.get(mc.get("mc_attr_name")));
				mc_ds = this.daoSupport.find(sql);
			}
			return mc_ds;
		}
		return null;
	}
	
	public Object getDataValue(int ds_id,Object k){
		try{
		Map<String,Object> ds = this.daoSupport.findOne("sys_ds",null,"ds_id = "+ds_id);
		if(null!=ds && ds.size()>0){
			String ds_type_val = ds.get("ds_type").toString();
			if("map".equals(ds_type_val)){
				String ds_map = ds.get("ds_collection").toString();
				String[] ds_map_split = ds_map.split(",");
				for(String s : ds_map_split){
					if(k!=null && s.startsWith(k.toString())){
						return s.substring(k.toString().length()+1);
					}
				}
			}else if("sql".equals(ds_type_val)){
				Map<String,Object> v_map = this.daoSupport.findOne(" (" + ds.get("ds_sql").toString()+") as t ","v","k = "+k);
				if(null == v_map)
					return k;
				return v_map.get("v");
			}
		}
		}catch(Exception hex){
			return null;
		}
		return k;
	}
	
	protected Map<String,String> getControls(String m_id,Map<String,Object> e) throws Throwable{
		
		Map<String,String> tmp = new HashMap<String,String>();
		Map<String,Object> m = this.daoSupport.findOne("sys_model",null,"m_id = "+m_id);
		tmp.put("v",m.get("m_view").toString());
		rst.setReqAttribute("model", m);
		List<Map<String,Object>> controls = this.daoSupport.find("sys_model_control mc,sys_control c", 
				"mc.*,c.*",
				"mc.mc_control_id = c.c_id and mc.mc_model_id = "+m_id,
				"mc_index");
		for(int i = 0;i<controls.size();i++){
			Map<String,Object> c = controls.get(i);
			if("1".equals(c.get("mc_pri").toString()))
				tmp.put("pri",c.get("mc_attr_name").toString());
			Object ds_id = c.get("mc_ds");
			if(null == ds_id) continue;
			if("0".equals(ds_id.toString().trim())) continue;
			StringBuffer sb = new StringBuffer();
			List<Map<String,Object>> ds = this.getDataSource("mc_ds",ds_id);
			for(Map<String,Object> d : ds){
				sb.append("<option value='").append(d.get("k")).append("' ");
				//checked the current value
				if(e.get(c.get("mc_attr_name")).toString().trim().equals(d.get("k").toString().trim()))
				{
					sb.append("selected='selected'");
				}
				sb.append(" >").append(d.get("v")).append("</option>");
			}
			c.put("mc_ds", sb.toString());
			controls.set(i, c);
		}
		rst.setCode(0).setReqAttribute("controls", controls);
		return tmp;
	}
	
	public BizResult form(Map<String,String> input) throws Throwable{
		
		String m_id = input.get("m_id");
		String p =input.get("p");
		if("add".equals(p)){
			//添加表单
			rst.setReqAttribute("p", "add");
			//判断该模型是否关联了工作流
			Map<String,Object> tm = this.daoSupport.findOne("wf_tpl_model", "*", "tm_act = 'add' and tm_m = "+m_id);
			rst.setReqAttribute("tm",tm );
			getControls(m_id);
		}else if("edit".equals(p)){
			//修改表单
			//TODO..加载属性
			String e_id = input.get("key");
			String pri = input.get("pri");
			String v = input.get("v");
			Map<String,Object> e = this.daoSupport.findOne(v,null,pri+"="+e_id);
			getControls(m_id,e);
			rst.setReqAttribute("e",e )
				.setReqAttribute("p", "edit")
				.setReqAttribute("pri", pri)
				.setReqAttribute("key", e_id)
				.setReqAttribute("v",v);
		}
		return rst.setCode(0).setType(BizResult.REDIRECT)
				.setPage("WIDGETS/TPL/form.jsp");
	}
	
	public BizResult delete(Map<String,String> input) throws Throwable{
		String key = input.get("key");
		//可处理多个值,'_'
		String[] keys = key.split("_");
		String pri = input.get("pri");
		String where;
		if(keys.length>1){
			where = pri+" in " + Arrays.toString(keys).replace("[", "(").replace("]", ")");
		}else{
			where = pri+"="+key; 
		}
		if(this.daoSupport.delete(input.get("v"),where)>0){
			rst.setCode(0).setMsg("OK");
		}else{
			return  rst.setCode(-102).setMsg("删除实例时发生了异常！");
		}
		//如果是员工业务办理删除，则要删除流程信息
		if("usr_matter".equals(input.get("v"))){
			if(keys.length>1){
				where = "e_ref_id in " + Arrays.toString(keys).replace("[", "(").replace("]", ")");
			}else{
				where = "e_ref_id ="+key; 
			}
			
			if(1>this.daoSupport.delete("wf_entry",where)){
				return rst.setCode(-103).setMsg("删除实例关联的工作流信息时发生了异常！");
			}
		}
		return rst;
	}
	
	public BizResult detail(Map<String,String> input)throws Throwable{
		
		String log = input.get("log");
		if("1".equals(log)){
			rst.setReqAttribute("logs",
					this.daoSupport.find("wf_process p,usr_userinfo u" , 
							"p.*,u.*", 
							"p.p_deal_user = u.ui_id and p.p_entry = "+input.get("e_id"), "p.p_deal_date desc"));
		}
		String m_id = input.get("m_id");
		if("-1".equals(m_id)){
			//-1标记该条流程为手动发起的流程，未关联其他模型表单
			
		}else{
			Map<String,String> tmp = getControls(m_id);
			String e_id = input.get("key");
			String pri = tmp.get("pri");
			String v = tmp.get("v");
			
			rst.setReqAttribute("e", this.daoSupport.findOne(v,null,pri+"="+e_id));
		}
		return rst.setCode(0)
				.setType(BizResult.REDIRECT)
				.setPage("WIDGETS/TPL/detail.jsp");
	}
	
	
	public BizResult edit(Map<String,String> input)throws Throwable{
		String key = input.get("key");
		String pri = input.get("pri");
		String v = input.get("v");
		if(1 == this.daoSupport.update(input, pri+"="+key, v)){
			rst.setReqAttribute("msg", "OK");
		}else{
			rst.setReqAttribute("msg", "更新数据时发生了异常");
		}
		return list(input);
	}
	
	public BizResult add(Map<String,String> input) throws Throwable{
		String m_id = input.get("m_id");
		Object ref_id = null;
		Map<String,Object> model = this.daoSupport.findOne("sys_model",null,"m_id = "+m_id);
		rst.setReqAttribute("model", model);
		ref_id = this.daoSupport.insert(model.get("m_view").toString(),input );
		rst.setData(ref_id);
		//用户自发创建的工作流程
		if(input.containsKey("m_title")){
			input.put("title", input.get("m_title"));
		}
		return rst.setCode(0).setType(BizResult.ECHO);
		//return workflow(input,"add",ref_id.toString());
	}
	
	/**
	 * 业务触发工作流
	 * @param input
	 * @return
	 */
	public BizResult workflow(Map<String,String> input,String o,String ref_id) throws Throwable{
		
		Map<String,Object> model = rst.getReqAttribute("model");
		//是否需要挂接工作流
		Map<String,Object> wf = this.daoSupport.findOne("wf_tpl_model",null,"tm_act = '"+o+"' and tm_m = "+model.get("m_id"));
		String wf_id = "";
		if(wf==null){
			if(!input.containsKey("wf")){
				return list(input);
			}
			wf_id = input.get("wf");
		}else{
			wf_id = wf.get("tm_t").toString();
		}
		input.put("wf", wf_id);
		String title = null;
		Map<String,Object> user = rst.getSissAttribute(GlobalKey.USER);
		if(input.containsKey("title")){
			title = input.get("title");
		}else{
			title = user.get("ui_nickname")+"提交:"+model.get("m_title");
		}
		input.put("m_title", title);
		
		return createMatter(input);
	}
	
	public BizResult createMatter(Map<String,String> input)throws Throwable{
		//创建流程的操作
		//加载面板
		Map<String,Object> user = rst.getSissAttribute(GlobalKey.USER);
		String nowtime = TimeUtil.getNow();
		String curuser = user.get("ui_id").toString();
		String tpl_id = input.get("wf");
		input.put("m_user",curuser);
		input.put("m_start_date", nowtime);
		//创建业务信息
		int lastid = daoSupport.insert( "usr_matter",input);
		//创建流程实例
		Map<String,String> e = new HashMap<String,String>();
		e.put("e_title", input.get("m_title"));
		e.put("e_create_date", nowtime);
		e.put("e_update_date", nowtime);
		e.put("e_cur_user", curuser);
		e.put("e_tpl",tpl_id);
		e.put("e_node","1");
		e.put("e_ref_id",String.valueOf(lastid));
		e.put("e_status", "start");
		e.put("e_model_id","-1");//
		lastid = daoSupport.insert( "wf_entry",e);
		rst.setReqAttribute("p_entry", lastid).setReqAttribute("p_node", "1");
		//加载处理结果数据源
		//rst.setReqAttribute("result", daoSupport.getDataSource("ds_name", "流程处理结果"));
		//获取流程模板的信息
		List<Map<String,Object>> nodes = daoSupport.find("wf_node",null,"n_tpl = " +tpl_id,"n_code");
		rst.setReqAttribute("nodes",nodes);
		//获取下一节点的审批部门的用户
		rst.setReqAttribute("next_users", daoSupport.find("usr_userinfo ui,usr_obs o ","ui.ui_id as k,CONCAT(o.o_name,'-',ui.ui_nickname) as v","ui.ui_dept = o.o_id and o.o_id in (select n_cur_obs from wf_node where n_tpl = "+tpl_id+" and n_prev_code = '1')",null));
		rst.setReqAttribute("p_result", "start");
		rst.setReqAttribute("m_reason",input.get("m_reason"));
		//this.isajax = false;
		return rst.setCode(0).setType(BizResult.REDIRECT).setPage("WIDGETS/WF/process.jsp");
	}

}
